package com.libreaccess.reporting.portlet;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPdfExporterParameter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.type.WhenNoDataTypeEnum;

import java.sql.Connection;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.springframework.stereotype.Service;

import com.libreaccess.reporting.beans.ReportsDAO;
import com.libreaccess.reporting.scheduler.CronTriggerExpr;
import com.libreaccess.reporting.scheduler.SchedulerManager;
import com.libreaccess.reporting.utils.CustomFileResolver;
import com.libreaccess.reporting.utils.Logger;
import com.libreaccess.reporting.utils.ReportUtil;
import com.libreaccess.reporting.utils.ReportingEnums;
import com.libreaccess.reporting.utils.ReportingPortletDataPerUser;
import com.libreaccess.reporting.utils.SimpleUtils;
import com.libreaccess.reporting.utils.JasperUtils;
import com.libreaccess.reporting.utils.mockData;
import com.libredigital.reporting.schema.MyReport;
import com.libredigital.reporting.schema.OutputFormat;
import com.libredigital.reporting.schema.Report;
import com.libredigital.reporting.schema.ReportView;
import com.libredigital.reporting.schema.Response;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.model.User;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portlet.PortletURLUtil;

import javax.annotation.Resource;
import javax.naming.NamingException;
import javax.portlet.*;

import java.net.URLDecoder;

@Service(value = "reportsController")
public class ReportingPortlet extends GenericPortlet {

	@Resource
	private static ReportsDAO rDao;

	public void setrDao(ReportsDAO reports) {
		ReportingPortlet.rDao = reports;
	}
	public static final String LOGGED_USER_EMAIL = "LOGGED_USER_EMAIL";
	public static final String REPORT_KEY = "JASPER_REPORT_KEY";
	public static final String REPORT_VIEW_KEY = "JASPER_REPORT_VIEW_KEY";
	public static final String ALL_REPORTS = "ALL_JASPER_REPORTS";
	public static final String ALL_REPORT_VIEW = "ALL_REPORT_VIEW";
	public static final String CURRENT_REPORT_ID = "CURRENT_REPORT_ID";
	public static final String CURRENT_REPORT_VIEW = "CURRENT_REPORT_VIEW";
	public static final String DISPLAY_SELECTED_REPORT = "DISPLAY_SELECTED_REPORT";
	public static final String DISPLAY_SELECTED_TYPE = "DISPLAY_SELECTED_TYPE";
	public static final String DISPLAY_SELECTED_SUMMARY = "DISPLAY_SELECTED_SUMMARY";
	public static final String DISPLAY_SELECTED_PARAMETERS = "DISPLAY_SELECTED_PARAMETERS";
	public static final String DISPLAY_SELECTED_OUTPUT = "DISPLAY_SELECTED_OUTPUT";
	public static final String TAB_SELECTED = "TAB_SELECTED";
	public static final String HELP_URL = "HELP_URL";
	public static final String REPORT_PARAMETERS = "REPORT_PARAMETERS";
	public static final String SELECTED_FORMAT = "SELECTED_FORMAT";
	public static final String ALL_OUTPUTFORMATS = "ALL_OUTPUTFORMATS";
	public static final String MY_REPORTS = "MY_REPORTS";
	public static final String COMPLETED_REPORTS = "COMPLETED_REPORTS";
	public static final String MY_REPORT_NAME = "MY_REPORT_NAME";
	public static final String MY_REPORT_NAME_IN_THE_DB = "MY_REPORT_NAME_IN_THE_DB";
	public static final String WINDOW_STATE = "WINDOW_STATE";
	public static final String SCHEDULER_START_DATE = "SCHEDULER_START_DATE";
	public static final String SCHEDULER_FREQUENCY = "SCHEDULER_FREQUENCY";
	public static final String SCHEDULER_EMAIL = "SCHEDULER_EMAIL";
	public static final String SCHEDULER_RECURRING_COUNT = "SCHEDULER_RECURRING_COUNT";
	public static final String SCHEDULER_DAY = "SCHEDULER_DAY";
	public static final String SCHEDULER_IS_CALENDAR = "SCHEDULER_IS_CALENDAR";
	public static final String SCHEDULER_DAY_NAME = "SCHEDULER_DAY_NAME";
	public static final String SCHEDULER_DAY_PREFIX = "SCHEDULER_DAY_PREFIX";
	public static final String IS_SCHEDULER_VISIBLE = "IS_SCHEDULER_VISIBLE";
	public static final String LINK_TO_BACK = "LINK_TO_BACK";
	public static final String LINK_TO_MESSAGE = "LINK_TO_MESSAGE";
	
	private boolean isTest = false;

	private HashMap<String, ReportingPortletDataPerUser> usersPrivateData = new HashMap<String, ReportingPortletDataPerUser>();
	
	final Logger logger = new Logger(getClass());

	public void setUsersPrivateData(HashMap<String, ReportingPortletDataPerUser> usersPrivateData) {
		this.usersPrivateData = usersPrivateData;
	}
	public HashMap<String, ReportingPortletDataPerUser> getUserPrivateData() {
		return usersPrivateData;
	}
/* this method calls when we read any data from application (post/get)
 * @see javax.portlet.GenericPortlet#processAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse)
 * @param ActionRequest request
 * @param ActionResponse response
 * @return void
 */
	public void processAction(ActionRequest request, ActionResponse response) {
		logger.debug("I'm in processAction");	
		ReportingPortletDataPerUser sessionData = setSessionId(request);
		//set Maximize/Minimize when it needs
		try {
			if (request.getParameter("maximize") != null && request.getWindowState() == WindowState.MAXIMIZED)
			{
				response.setWindowState(WindowState.NORMAL);
				logger.debug("Window state was changed to NORMAL");
			}
			else 
			{
				if (request.getParameter("maximize") != null && request.getWindowState() == WindowState.NORMAL)
				{
					response.setWindowState(WindowState.MAXIMIZED);
					logger.debug("Window state was changed to MAXIMIZED");
				}
			}
		} catch (WindowStateException e) 
		{
			logger.error("Maximize button incorrect works: "+e.getMessage());
		}
		
		sessionData.setWindow(ReportingEnums.Window.valueOf(request.getParameter("sWindow") != null
				?request.getParameter("sWindow").toString():"reportManager"));
		setPrivateSessionData(sessionData.getSessionId(),sessionData);

		logger.debug("sWindow = " + sessionData.getWindow());

		switch (sessionData.getWindow())
		{
		case reportDefinition:
			getDefinitionData(request, response);
			break;
		case reportManager:
			getManagerData(request, response);
			break;
		}
	}

	/* this method calls when we display / redisplay our application in LifeRay
	 * @see javax.portlet.GenericPortlet#doView(javax.portlet.RenderRequest, javax.portlet.RenderResponse)
	 * @param RenderRequest request
	 * @param RenderResponse response
	 * @return void
	 */
	public void doView(RenderRequest request, RenderResponse response)
			throws IOException, PortletException {
		request.setAttribute(WINDOW_STATE, request.getWindowState());
		
		String url = PortletURLUtil.getCurrent(request, response).toString();
		url = url.substring(0,url.indexOf("?"));
		logger.debug("url:"+url);

		ReportingPortletDataPerUser sessionData = setSessionId(request);
		sessionData.getReportUtil().setUrl(url+"?getreport=");
		
//		if (sessionData.getWindow()==null) sessionData.setWindow(ReportingEnums.Window.reportManager); //impossible  
		setPrivateSessionData(sessionData.getSessionId(), sessionData);
		switch (sessionData.getWindow()) 
		{
			case reportManager:
				displayManagerData(request, response);
				break;
			case reportDefinition:
				displayDefinitionData(request, response);
				break;
		}
	}

	/* this method calls when we use resources (such as image or reports)
	 * @see javax.portlet.GenericPortlet#serveResource(javax.portlet.ResourceRequest, javax.portlet.ResourceResponse)
	 * @param ResourceRequest request
	 * @param ResourceResponse response
	 * @return void
	 */
	public void serveResource(ResourceRequest request, ResourceResponse response) {
		logger.debug("******serveResource START section***************************");

		String whoRuns = ParamUtil.getString(request, "whoRuns");
		logger.debug("WhoRuns:"+whoRuns);
		
		if (whoRuns.equalsIgnoreCase("report")/*button run now is pressed*/ 
			|| request.getParameter("image") != null /*find resource such as images*/){
			serveResourceGenerateNow(request, response);
		}
		else if (whoRuns.equalsIgnoreCase("completedReport")/*button edit completed reports now is pressed*/ 
				|| request.getParameter("completedReportImage") != null /*find resource such as images*/){ 
			serveResourceCompletedReports(request, response);
		}
			
		logger.debug("******serveResource END section***************************");
	}


	/* this method calls when we use resources (such as image or reports). They are located in memmory
	 * @param ResourceRequest request
	 * @param ResourceResponse response
	 * @return void
	 */
	private void serveResourceGenerateNow(ResourceRequest request, ResourceResponse response) {
		logger.debug("******serveResourceGenerateNow START section***************************");
		ReportingPortletDataPerUser sessionData = setSessionId(request);
		try {
						OutputStream out = response.getPortletOutputStream();
						if (request.getParameter("image") == null)
						{
							ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();			
							String rptName = String.format("%s_%s", sessionData.getReportName(), SimpleUtils.formatCurrentDate());
							
							switch(sessionData.getReportUtil().getReportFormat())
							{
							case PDF:
								JRPdfExporter exporterPDF = new JRPdfExporter();
								exporterPDF.setParameter(JRPdfExporterParameter.JASPER_PRINT, sessionData.getPrint());
								exporterPDF.setParameter(JRPdfExporterParameter.OUTPUT_STREAM, byteArrayOutputStream);
								exporterPDF.exportReport();

								// Prepare your pdf here
								response.setContentType("application/pdf");
								PortalUtil.getHttpServletResponse(response).setHeader("Content-Disposition", "attachment; filename=\"" + rptName + ".pdf\";");
							
								out.write(byteArrayOutputStream.toByteArray());
								break;
							case CSV:
								JRCsvExporter exporterCSV = new JRCsvExporter();
								exporterCSV.setParameter(JRXlsExporterParameter.JASPER_PRINT, sessionData.getPrint());
								exporterCSV.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, byteArrayOutputStream);
								exporterCSV.exportReport();

								//Prepare you csv here
								response.setContentType("text/csv");
								PortalUtil.getHttpServletResponse(response).setHeader("Content-Disposition", "attachment; filename=\"" + rptName + ".csv\";");

								out.write(byteArrayOutputStream.toByteArray());
								break;
							case XLS:
								JRXlsExporter exporterXLS = new JRXlsExporter();
								exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT, sessionData.getPrint());
								exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, byteArrayOutputStream);
								exporterXLS.exportReport();

								//Prepare you xls here
								response.setContentType("application/ms-excel");
								PortalUtil.getHttpServletResponse(response).setHeader("Content-Disposition", "attachment; filename=\"" + rptName + ".xls\";");

								out.write(byteArrayOutputStream.toByteArray());
								break;
							case HTML:
								sessionData.imagesMap = new HashMap<String, Object>();
								StringBuffer sbuffer = new StringBuffer();
								JRHtmlExporter exporter = new JRHtmlExporter();

								exporter.setParameter(JRExporterParameter.JASPER_PRINT, sessionData.getPrint());
								exporter.setParameter(JRExporterParameter.OUTPUT_STRING_BUFFER, sbuffer);
								exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, sessionData.imagesMap);
								exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, PortalUtil.getCurrentURL(request)+"&image=");
							
			/*					exporter.setParameter(JRHtmlExporterParameter.HTML_HEADER, "");
								exporter.setParameter(JRHtmlExporterParameter.BETWEEN_PAGES_HTML, "");
								exporter.setParameter(JRHtmlExporterParameter.HTML_FOOTER, "");*/
							
								exporter.exportReport();
								
								response.setContentType("text/html");
								
								String js = "<script language=\"JavaScript\">javascript:window.history.forward(1);</script>";
								   
								sbuffer.insert(0, js);
								out.write(sbuffer.toString().getBytes());
								break;
							}
							sessionData.getReportUtil().setParameters(null);
							setPrivateSessionData(sessionData.getSessionId(), sessionData);
							logger.debug("paramValues was cleared");
						}
						else
						{
							logger.debug("need the image:"+request.getParameter("image"));
							byte[] imageData = (byte[])sessionData.imagesMap.get(request.getParameter("image"));
							response.setContentLength(imageData.length);
							out.write(imageData, 0, imageData.length);
						}
						
						out.flush();
						out.close();
					} catch (Exception e) {
						logger.error("the report could not be generated: "+e.getMessage());
					}
					logger.debug("******serveResourceGenerateNow END section***************************");
	}
	

	/* (private)this method calls when we use resources (such as image or reports). They are located in File System
	 * @param ResourceRequest request
	 * @param ResourceResponse response
	 * @return void
	 */
	private void serveResourceCompletedReports(ResourceRequest request, ResourceResponse response) {
		logger.debug("******serveResourceCompletedReports START section***************************");
		ReportingPortletDataPerUser sessionData = setSessionId(request);
		try {
				OutputStream out = response.getPortletOutputStream();
				File file = new File(sessionData.getReportUtil().getReportsFolder()+File.separator+sessionData.getCompletedReportName());
						
				if (request.getParameter("completedReportImage") == null)
				{
					if (file != null && file.exists())
					{
						logger.debug("file:"+file.getName()+" exists");
						String extOnly = file.getName().substring(file.getName().lastIndexOf('.')+1);
						ReportingEnums.Format format = ReportingEnums.Format.valueOf(extOnly.toUpperCase());
						logger.debug("Format file:"+format.toString());

						switch (format) {
						case PDF:
							response.setContentType("application/pdf");
							PortalUtil.getHttpServletResponse(response).setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + ".pdf\";");
							out.write(JasperUtils.getBytesFromFile(file));
							break;
						case CSV:
							response.setContentType("text/csv");
							PortalUtil.getHttpServletResponse(response).setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + ".csv\";");
							out.write(JasperUtils.getBytesFromFile(file));
							break;
						case XLS:
							response.setContentType("application/ms-excel");
							PortalUtil.getHttpServletResponse(response).setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + ".xls\";");
							out.write(JasperUtils.getBytesFromFile(file));
							break;
						case HTML:
							response.setContentType("text/html");
							String js = "<script language=\"JavaScript\">javascript:window.history.forward(1);</script>";
									   
							out.write(js.getBytes());
							out.write((new String(JasperUtils.getBytesFromFile(file)).replaceAll(file.getName()+"_files/", PortalUtil.getCurrentURL(request)+"&completedReportImage=")).getBytes());
							break;
						}

					} else {
						logger.warn("File: '"+sessionData.getReportUtil().getReportsFolder()+File.separator+sessionData.getCompletedReportName()+"' does not exist");								
					}
				} else {/* get image as resource*/
					logger.debug("need the image:"+request.getParameter("completedReportImage"));
					File fileRes = new File(sessionData.getReportUtil().getReportsFolder()+File.separator+file.getName()+ "_files" + File.separator + request.getParameter("completedReportImage"));
					if (fileRes != null && fileRes.exists())
					{
						byte[] imageData = JasperUtils.getBytesFromFile(fileRes);
						response.setContentLength(imageData.length);
						out.write(imageData, 0, imageData.length);
					}
					else
					{
						logger.warn("Resource File: '"+sessionData.getReportUtil().getReportsFolder()+File.separator+fileRes.getName()+"' does not exist");
					}
				}
				out.flush();
				out.close();
			} catch (IOException e) {
				logger.error("Completed Report is not working correctly: "+e.getMessage());
			}
						
			logger.debug("******serveResourceCompletedReports START section***************************");
	}		


	/* (private)this method calls when get data from Reporting Application: manager page 
	 * @param ActionRequest request
	 * @param ActionResponse response
	 * @return void
	 */
	private void getManagerData(ActionRequest request, ActionResponse response) {
		logger.debug("******getManagerData START section***************************");
		ReportingPortletDataPerUser sessionData = getPrivateSessionData(request);
		System.out.println("dfdfdsgfdsgdfs:"+request.getParameter("sButton"));
		if (/*request.getParameter("sButton") != null && */!SimpleUtils.isStringEmpty(request.getParameter("sButton")))
		{
			sessionData.setBtnPressedId(ReportingEnums.ButtonIds.valueOf(request.getParameter("sButton")));
			logger.debug("Button pressed:"+sessionData.getBtnPressedId());

			sessionData.setIsDefaultAction(request.getParameter("isDefaultAction") != null ? 
					request.getParameter("isDefaultAction").toString().toLowerCase():"false");
			logger.debug("isDefaultAction:"+sessionData.getIsDefaultAction());
				
			switch(sessionData.getBtnPressedId())
			{
			case deleteCompletedReportBtn:
			case viewCompletedReportBtn:
				sessionData.setCompletedReportName(request.getParameter("completedReportName") != null 
					? request.getParameter("completedReportName").toString() : "");
				logger.debug("Completed Report Name:"+sessionData.getCompletedReportName());
				break;
			case deleteBtn:
				sessionData.getReportUtil().setMyReportId(!SimpleUtils.isStringEmpty(request.getParameter("sReportId")) 
					? Long.parseLong(request.getParameter("sReportId").toString()) : 0l);
				logger.debug("selected to delete report id = " + sessionData.getReportUtil().getMyReportId());
				break;
			case runNowBtn:
				sessionData.getReportUtil().setMyReportId(!SimpleUtils.isStringEmpty(request.getParameter("sReportId")) 
					? Long.parseLong(request.getParameter("sReportId").toString()) : 0l);
				logger.debug("selected report id = " + sessionData.getReportUtil().getMyReportId());
					if (sessionData.getReportUtil().getMyReportId() != 0l)
					{
						try {
							MyReport myRep = rDao.getMyReportById(sessionData.getReportUtil().getMyReportId());
							ReportUtil ru = JasperUtils.GetReportUtilFromByteArray(myRep.getParameters());
					
							sessionData.setCurrentReportId(myRep.getReportId());
								logger.debug("CurrentReportId = " + sessionData.getCurrentReportId());
					
							sessionData.setCurrentViewId(myRep.getViewId());
							logger.debug("CurrentViewId = " + sessionData.getCurrentViewId());
								
							sessionData.setMyReportName(myRep.getName());
							logger.debug("my report name = " + sessionData.getMyReportName()); 
							
							sessionData.setMyReportNameInDB(myRep.getName());
							logger.debug("my report name (from db) = " + sessionData.getMyReportNameInDB()); 
								if (ru!= null)
								{
									sessionData.getReportUtil().setReportFormat(ru.getReportFormat());
									logger.debug("format = " + sessionData.getReportUtil().getReportFormat());
						
									sessionData.getReportUtil().setParameters(ru.getParameters());
									logger.debug("parameters = " + sessionData.getReportUtil().getParameters());
									
									sessionData.getReportUtil().setTriggerExpr(ru.getTriggerExpr());
									logger.debug("scheduler trigger expr = " + ru.getTriggerExpr());
								}

							} catch (NamingException e) {
									logger.error("Can't get myReport "+e.getMessage());
							} catch (SQLException e) {
									logger.error("Can't get myReport "+e.getMessage());
							}
						}
						break;
				}
			}
			else
			{
				sessionData.setBtnPressedId(null);
			}
			setPrivateSessionData(sessionData.getSessionId(), sessionData);

		logger.debug("******getManagerData END section***************************");
	}


	/* (private)this method calls when get data from Reporting Application: definition page 
	 * @param ActionRequest request
	 * @param ActionResponse response
	 * @return void
	 */
	private void getDefinitionData(ActionRequest request, ActionResponse response) {
		logger.debug("******getDefinitionData START section***************************");
		ReportingPortletDataPerUser sessionData = getPrivateSessionData(request);
		if (/*request.getParameter("sButton") != null && */!SimpleUtils.isStringEmpty(request.getParameter("sButton")))
		{
			sessionData.setBtnPressedId(ReportingEnums.ButtonIds.valueOf(request.getParameter("sButton")));
			logger.debug("Button pressed:"+sessionData.getBtnPressedId());
			switch(sessionData.getBtnPressedId())
			{
			case newBtn:
				sessionData.clearData();
				sessionData.setBtnPressedId(ReportingEnums.ButtonIds.newBtn);
				sessionData.setWindow(ReportingEnums.Window.reportDefinition);
				sessionData.getReportUtil().setParameters(null);  //it's need otherwise new report will be have filled parameter values
				sessionData.getReportUtil().setTriggerId(null);  //it's need otherwise new report won't create new scheduler trigger, it will be replace existed
				setPrivateSessionData(sessionData.getSessionId(), sessionData);
			break;
			case editBtn:
				sessionData.getReportUtil().setMyReportId(!SimpleUtils.isStringEmpty(request.getParameter("sReportId")) 
					? Long.parseLong(request.getParameter("sReportId").toString()) : 0l);
				logger.debug("selected report id = " + sessionData.getReportUtil().getMyReportId()); 
				
				if (sessionData.getReportUtil().getMyReportId() != 0l)
				{
					try {
						MyReport myRep = rDao.getMyReportById(sessionData.getReportUtil().getMyReportId());
						ReportUtil ru = JasperUtils.GetReportUtilFromByteArray(myRep.getParameters());
					
						sessionData.setCurrentReportId(myRep.getReportId());
						logger.debug("CurrentReportId = " + sessionData.getCurrentReportId()); 
					
						sessionData.setCurrentViewId(myRep.getViewId());
						logger.debug("CurrentViewId = " + sessionData.getCurrentViewId()); 

						sessionData.setMyReportName(myRep.getName());
						logger.debug("my report name = " + sessionData.getMyReportName()); 

						sessionData.setMyReportNameInDB(myRep.getName());
						logger.debug("my report name (from db) = " + sessionData.getMyReportNameInDB()); 

							/*it needs to move into daoImpl class!!!*/
							if (ru!= null)
							{
								sessionData.getReportUtil().setReportFormat(ru.getReportFormat());
								logger.debug("format = " + sessionData.getReportUtil().getReportFormat()); 

								//sessionData.getReportUtil().setSchedulerVisible(ru.getSchedulerVisible());
								sessionData.getReportUtil().setSchedulerVisible(!SimpleUtils.isStringEmpty(myRep.getScheduleNextRun()));
								logger.debug("scheduler is visible = " + ru.getSchedulerVisible()); 

								if (ru.getSchedulerVisible())
								{
									sessionData.getReportUtil().setSchedulerCountToRun(ru.getSchedulerCountToRun());
								}
								else
								{
									sessionData.getReportUtil().setSchedulerCountToRun(0);  //remove scheduler if it isn't visible
								}
								logger.debug("scheduler count to run = " + sessionData.getReportUtil().getSchedulerCountToRun()); 
									
								sessionData.getReportUtil().setSchedulerStartDate(ru.getSchedulerStartDate());
								logger.debug("scheduler start date = " + sessionData.getReportUtil().getSchedulerStartDate()); 

								sessionData.getReportUtil().setSchedulerDay(ru.getSchedulerDay());
								logger.debug("scheduler day = " + sessionData.getReportUtil().getSchedulerDay()); 
								
								sessionData.getReportUtil().setSchedulerRecurringDate(ru.getSchedulerRecurringDate());
								logger.debug("getSchedulerRecurringDate = " + sessionData.getReportUtil().getSchedulerRecurringDate()); 
								
								sessionData.getReportUtil().setSchedulerRecurringDatePrefix(ru.getSchedulerRecurringDatePrefix());
								logger.debug("getSchedulerRecurringDatePrefix = " + sessionData.getReportUtil().getSchedulerRecurringDatePrefix()); 
								
								sessionData.getReportUtil().setIsCalendarchoosed(ru.getIsCalendarchoosed());
								logger.debug("IsCalendarchoosed = " + sessionData.getReportUtil().getIsCalendarchoosed()); 
								
								sessionData.getReportUtil().setSchedulerFrequency(ru.getSchedulerFrequency());
								logger.debug("scheduler frequency = " + sessionData.getReportUtil().getSchedulerFrequency()); 
								
//								sessionData.setReportUtil(Utils.ReportUtilValues.email, ru.getEmail());
								sessionData.getReportUtil().setEmail(ru.getEmail());
								logger.debug("scheduler email = " + sessionData.getReportUtil().getEmail()); 
								
								if ((ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY) != null) {
								List<User> users = UserLocalServiceUtil.getUsers(0, UserLocalServiceUtil.getUsersCount());
								
									sessionData.getReportUtil().setRecipients(JasperUtils.fillRecipients(users, ru.getEmail()));
								}
								
								logger.debug("recipients = " + sessionData.getReportUtil().getRecipients()); 
								
								sessionData.getReportUtil().setTriggerId(ru.getTriggerId());
								logger.debug("scheduler trigger id = " + sessionData.getReportUtil().getTriggerId()); 
								
								sessionData.getReportUtil().setTriggerExpr(ru.getTriggerExpr());
								logger.debug("scheduler trigger expr = " + ru.getTriggerExpr()); 

 
//								logger.debug("*******************************************************************************");
//								logger.debug("I'm in get data (edit) trigger id is " + sessionData.getReportUtil().getTriggerId() !=null ? sessionData.getReportUtil().getTriggerId():"");
//								logger.debug("*******************************************************************************");

								sessionData.getReportUtil().setParameters(ru.getParameters()); 
							}
							setPrivateSessionData(sessionData.getSessionId(), sessionData);
						
						} catch (NamingException e) {
							logger.error("Can't get Report: "+e.getMessage());
						} catch (SQLException e) {
							logger.error("Can't get Report: "+e.getMessage());
						} catch (SystemException e) {
							logger.error("Can't get Report: "+e.getMessage());
						}
					}
					else
					{
						setPrivateSessionData(sessionData.getSessionId(), sessionData);
						getPrimaryDefinitionData(request,response);	
					}
					break;
				case saveBtn:
				case viewBtn:
					setPrivateSessionData(sessionData.getSessionId(), sessionData);
					getPrimaryDefinitionData(request,response);
					break;
				}
			}
			else
			{
				sessionData.setBtnPressedId(null);
				setPrivateSessionData(sessionData.getSessionId(), sessionData);
				getPrimaryDefinitionData(request,response);
			}

			logger.debug("Session id is "+sessionData.getSessionId()); 

		logger.debug("******getDefinitionData END section***************************"); 
	}

	/* (private)this method calls when get data from any Reporting page 
	 * @param ActionRequest request
	 * @param ActionResponse response
	 * @return void
	 */
	private void getPrimaryDefinitionData(ActionRequest request, ActionResponse response)
	{
		ReportingPortletDataPerUser sessionData = getPrivateSessionData(request);

			sessionData.setTabSelected(request.getParameter("tab_selected") != null 
				? Long.parseLong(request.getParameter("tab_selected").toString()) : 0l);
			logger.debug("Tab selected = " + sessionData.getTabSelected());
			
			sessionData.setCurrentReportId(request.getParameter("reports") != null 
				? Long.parseLong(request.getParameter("reports").toString()) : null);
			logger.debug("CurrentReportId = " + sessionData.getCurrentReportId());

			if (sessionData.getTabSelected() == 1l) {
				System.out.println("request.getParameter('views'):"+request.getParameter("views"));
				sessionData.setCurrentViewId(request.getParameter("views") != null 
				? Long.parseLong(request.getParameter("views").toString()) : null);
			} else {
				sessionData.setCurrentViewId(request.getParameter("viewContents") != null 
				? Long.parseLong(request.getParameter("viewContents").toString()) : null);
			}
			logger.debug("CurrentViewId = " + sessionData.getCurrentViewId()); 

			sessionData.getReportUtil().setReportFormat(request.getParameter("outputFormats") != null 
					? ReportingEnums.Format.valueOf(request.getParameter("outputFormats").toString()) : ReportingEnums.Format.HTML);
			logger.debug("format = " + sessionData.getReportUtil().getReportFormat()); 

			sessionData.setMyReportName(request.getParameter("myReportName") != null
				? request.getParameter("myReportName").toString() : "");
			logger.debug("my report name = " + sessionData.getMyReportName()); 
			
			sessionData.getReportUtil().setSchedulerVisible(request.getParameter("isSchedulerVisible") != null && request.getParameter("isSchedulerVisible").toString().equalsIgnoreCase("true"));
			
//			sessionData.setReportUtil(Utils.ReportUtilValues.email, request.getParameter("recipients") != null
//				? request.getParameter("recipients").toString() : "");
			sessionData.getReportUtil().setEmail(request.getParameter("recipients") != null
					? request.getParameter("recipients").toString() : "");
			logger.debug("Scheduler's email = " + sessionData.getReportUtil().getEmail()); 

			if ((ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY) != null) {
				List<User> users;
				try {
					users = UserLocalServiceUtil.getUsers(0, UserLocalServiceUtil.getUsersCount());
					sessionData.getReportUtil().setRecipients(JasperUtils.fillRecipients(users, sessionData.getReportUtil().getEmail()));
				} catch (SystemException e) {
					logger.error("Can't get Report: "+e.getMessage());
				}
			
			}

				//get scheduler date and time
				Date d = null;
				DateFormat formatterDate = new SimpleDateFormat("MM/dd/yyyy HH:mm");
				if (request.getParameter("scheduleDate") != null && !SimpleUtils.isStringEmpty(request.getParameter("scheduleDate").toString()) && sessionData.getReportUtil().getSchedulerVisible())
				{
					try {
						sessionData.getReportUtil().getTriggerExpr().setNextFireTime(request.getParameter("nextFireDate") != null 
							? new SimpleDateFormat("MM/dd/yyyy").parse(request.getParameter("nextFireDate").toString()) : new Date());
						logger.debug("Next Fire Time = " + sessionData.getReportUtil().getTriggerExpr().getNextFireTime()); 
						
						d = formatterDate.parse(request.getParameter("scheduleDate").toString());
							
						
					} catch (ParseException e) {
						logger.error("ParseException:"+e.getMessage());
					}
					sessionData.getReportUtil().setSchedulerStartDate(d);
					logger.debug("Scheduler Start Date: "+ d); 
					
					sessionData.getReportUtil().setSchedulerFrequency(request.getParameter("frequency") != null
						? ReportingEnums.SchedulerFrequency.valueOf(request.getParameter("frequency").toString()) : ReportingEnums.SchedulerFrequency.OneTime);
					logger.debug("Scheduler frequency = " + sessionData.getReportUtil().getSchedulerFrequency().toString()); 
	
					switch (sessionData.getReportUtil().getSchedulerFrequency()) {
						case OneTime: 
								sessionData.getReportUtil().setSchedulerCountToRun(1l);
								logger.debug("Scheduler count to run = 1");
							break;
						case Daily:
							sessionData.getReportUtil().setSchedulerCountToRun(request.getParameter("recuringDaysCountDaily") != null
								? Long.parseLong(request.getParameter("recuringDaysCountDaily").toString()) : 0l);
							logger.debug("Scheduler count to run = "+ sessionData.getReportUtil().getSchedulerCountToRun());
							break;
						case Weekly:
							sessionData.getReportUtil().setSchedulerCountToRun(request.getParameter("recuringDaysCountWeekly") != null
								? Long.parseLong(request.getParameter("recuringDaysCountWeekly").toString()) : 0l);
							logger.debug("Scheduler count to run = "+ sessionData.getReportUtil().getSchedulerCountToRun());
							sessionData.getReportUtil().setSchedulerDay(request.getParameter("recuringTime") != null
									? Long.parseLong(request.getParameter("recuringTime").toString()) : 1l);
							logger.debug("Number day of week = "+ sessionData.getReportUtil().getSchedulerDay());
							break;
						case Monthly:
							sessionData.getReportUtil().setSchedulerCountToRun(request.getParameter("recuringDaysCountMonthly") != null
								? Long.parseLong(request.getParameter("recuringDaysCountMonthly").toString()) : 0l);
							logger.debug("Scheduler count to run = "+ sessionData.getReportUtil().getSchedulerCountToRun());
							sessionData.getReportUtil().setSchedulerDay(request.getParameter("recuringTime") != null
								? Long.parseLong(request.getParameter("recuringTime").toString()) : 1l);
							logger.debug("Number day of month = "+ sessionData.getReportUtil().getSchedulerDay());
							sessionData.getReportUtil().setSchedulerRecurringDate(request.getParameter("recuringMonthlyDay") != null
									? request.getParameter("recuringMonthlyDay").toString() : "");
							logger.debug("Recurring Monthly Day = "+ sessionData.getReportUtil().getSchedulerRecurringDate());
							sessionData.getReportUtil().setSchedulerRecurringDatePrefix(request.getParameter("recuringMonthlyDayRepetition") != null
									? request.getParameter("recuringMonthlyDayRepetition").toString() : null);
							logger.debug("Recurring Monthly Day Prefix= "+ sessionData.getReportUtil().getSchedulerRecurringDatePrefix());
							sessionData.getReportUtil().setIsCalendarchoosed(request.getParameter("monthlyGroup").toString().equalsIgnoreCase("each"));
							logger.debug("Is Calendar selected= "+ sessionData.getReportUtil().getIsCalendarchoosed());
							logger.debug("request.getParameter(monthlyGroup)= "+ request.getParameter("monthlyGroup"));
							break;
						case Yearly:
							sessionData.getReportUtil().setSchedulerCountToRun(request.getParameter("recuringDaysCountYearly") != null
								? Long.parseLong(request.getParameter("recuringDaysCountYearly").toString()) : 0l);
							logger.debug("Scheduler count to run = "+ sessionData.getReportUtil().getSchedulerCountToRun());
							sessionData.getReportUtil().setSchedulerDay(request.getParameter("recuringTime") != null
								? Long.parseLong(request.getParameter("recuringTime").toString()) : 1l);
							logger.debug("Number month of year = "+ sessionData.getReportUtil().getSchedulerDay());
							sessionData.getReportUtil().setSchedulerRecurringDate(request.getParameter("recuringYearlyDay") != null
								? request.getParameter("recuringYearlyDay").toString() : "");
							logger.debug("Recurring Yearly Day = "+ sessionData.getReportUtil().getSchedulerRecurringDate());
							sessionData.getReportUtil().setSchedulerRecurringDatePrefix(request.getParameter("recuringYearlyDayRepetition") != null
								? request.getParameter("recuringYearlyDayRepetition").toString() : null);
							logger.debug("recuringYearlyDayRepetition = " + sessionData.getReportUtil().getSchedulerRecurringDatePrefix());
							
/*							sessionData.setIsCalendarchoosed(request.getParameter("recuringDaysIsCalendar") != null
								? Boolean.parseBoolean(request.getParameter("recuringDaysIsCalendar").toString()) : false);*/
							
							break;
					}
				}
				else
				{
					sessionData.getReportUtil().setSchedulerStartDate(null);
					sessionData.getReportUtil().setSchedulerFrequency(ReportingEnums.SchedulerFrequency.OneTime);
					sessionData.getReportUtil().setSchedulerCountToRun(0L);
				}
				HashMap<String, String> prmValues = new HashMap<String, String>();
				if (sessionData.getDesign() != null && sessionData.getDesign().getParameters() != null){
					for (JRParameter p : sessionData.getDesign().getParameters()) {
						if (!p.isSystemDefined() && p.isForPrompting()) {
							prmValues.put(p.getName(), request.getParameter("prm_"+p.getName()) != null ? request.getParameter("prm_"+p.getName()) : "");
							logger.debug("------------------------------------------------");
							logger.debug("parameter's name:"+p.getName()+ " value:"+request.getParameter("prm_"+p.getName()));
							logger.debug("parameter type:"+p.getValueClassName());
							logger.debug("Parameter was successfully read:"+p.getName()+" value:"+ prmValues.get(p.getName()));
						}
					}
				}
				sessionData.getReportUtil().setParameters(prmValues);
				
				setPrivateSessionData(sessionData.getSessionId(), sessionData);
	}

	/* (private)this method calls when we show Reporting Application: manager page 
	 * @param RenderRequest request
	 * @param RenderResponse response
	 * @return void
	 */
	private void displayManagerData(RenderRequest request, RenderResponse response) {
		logger.debug("******Display Manager Data START section***************************");
		boolean isException = false;
		ReportingPortletDataPerUser sessionData = getPrivateSessionData(request);
			try {
				String url = PortletURLUtil.getCurrent(request, response).toString();
				System.out.println("url:"+url);
				if (url.indexOf("getreport=")>0)
				{
					logger.debug("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
					
					String completedReportName = url.substring(url.indexOf("getreport=")+"getreport=".length());
					completedReportName = URLDecoder.decode( completedReportName, "UTF-8");
					request.setAttribute("isOpenCompletedReport", "true");
					sessionData.setCompletedReportName(completedReportName);
					
					logger.debug("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
				}
				
					request.setAttribute("HELP_URL",System.getProperty("help.url", ""));
					if (sessionData.getBtnPressedId() != null && sessionData.getIsDefaultAction() != null && sessionData.getIsDefaultAction().equals("true"))
					{
						sessionData.setIsDefaultAction("false");
						switch(sessionData.getBtnPressedId())
						{
						case deleteCompletedReportBtn:
							logger.debug("Requested to delete file:'"+sessionData.getReportUtil().getReportsFolder()+File.separator+sessionData.getCompletedReportName() +"'");
							File file = new File(sessionData.getReportUtil().getReportsFolder()+File.separator+sessionData.getCompletedReportName());
							if (file != null && file.exists())
							{
								try {
									String extOnly = file.getName().substring(file.getName().lastIndexOf('.')+1);
									file.delete();
									logger.debug("file was '"+sessionData.getCompletedReportName()+"' successfully deleted:"); 
									if (extOnly.equalsIgnoreCase("HTML"))
									{
										File directory = new File(sessionData.getReportUtil().getReportsFolder()+File.separator+sessionData.getCompletedReportName()+"_files");
										if (directory != null && directory.isDirectory() && directory.exists())
										{
											File[] files = directory.listFiles();
											for (File f : files)
											{
												if (!f.delete())
												{
													logger.error("Failed to delete: '"+f.getPath()+"'");
												}
											}
											directory.delete();
											logger.debug("folder was '"+sessionData.getCompletedReportName()+"_files' successfully deleted:");
										}
									}
								}
								catch(Exception e) { logger.error("Exception:"+e.getMessage());}
							}
							else {
								logger.warn("File: '"+sessionData.getReportUtil().getReportsFolder()+File.separator+sessionData.getCompletedReportName()+"' does not exist"); 								
							}
							break;
						case viewCompletedReportBtn:
							request.setAttribute("isOpenCompletedReport", "true");
							break;
						case deleteBtn:
							
							/* Delete trigger if it exists */
							MyReport myRep = rDao.getMyReportById(sessionData.getReportUtil().getMyReportId());
							ReportUtil ru = JasperUtils.GetReportUtilFromByteArray(myRep.getParameters());
						
							/*it needs to move into daoImpl class!!!*/
							if (ru!= null && ru.getTriggerId() != null)
							{
								SchedulerManager.deleteJobAndTrigger(sessionData.getReportUtil().getTriggerId());
							}
							rDao.deleteMyReport(sessionData.getReportUtil().getMyReportId());
							break;
						case runNowBtn:
				
							ReportView currentReportView = rDao.getReportViewById(sessionData.getCurrentViewId());
							sessionData.setDesign(JasperUtils.loadReport(currentReportView.getJrxml().getBytes("UTF-8")));
							logger.debug("design was changed for reportView:"+currentReportView.getId()); 
				
							sessionData = JasperUtils.setupParameters(sessionData);
							setPrivateSessionData(sessionData.getSessionId(), sessionData);
							if (sessionData.getModel()!=null)	{
								logger.debug("All parameters are successfully filled"); 
								sessionData = getPrivateSessionData(request);
								Connection con;
								if (currentReportView != null)
								{
									if (currentReportView.getDatasourceId() != 0l)
									{
										con = JasperUtils.getReportViewConnection(rDao.getReportDSById(currentReportView.getDatasourceId()));
										logger.debug("Report View:"+currentReportView.getId()+" uses the connection with id:"+currentReportView.getDatasourceId()); 
										
									}
									else
									{
										con = JasperUtils.getDataSource().getConnection();
										logger.debug("Report View:"+currentReportView.getId()+" uses default connection");
									}
									HashMap<String, Object> mdl = sessionData.getModel();
									mdl.put(JRParameter.REPORT_FILE_RESOLVER, new CustomFileResolver(rDao.setLogMaster(currentReportView.getId(), sessionData.getReportUtil().getUserName(), sessionData.getParameters())));
									try {
										JasperReport jasperReport = JasperCompileManager.compileReport(sessionData.getDesign());
										if (jasperReport.getWhenNoDataTypeValue() == WhenNoDataTypeEnum.NO_PAGES) {
											jasperReport.setWhenNoDataType(WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);
										}
										sessionData.setPrint(JasperFillManager.fillReport(jasperReport, mdl, con));
										sessionData.setModel(mdl);
									}
									catch (Exception ex) {
										String urlBack = PortletURLUtil.getCurrent(request, response).toString();
										urlBack = urlBack.substring(0,urlBack.indexOf("?"));
										request.setAttribute(LINK_TO_BACK, urlBack);
										request.setAttribute(LINK_TO_MESSAGE, "There is an Error in the Report Query, please contact the System Administrator");
										PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/jsp/index.jsp");
										dispatcher.include(request, response);	
										isException = true;
										sessionData.setBtnPressedId(ReportingEnums.ButtonIds.cancelBtn);
									}
									finally {
										if (con != null) {
											con.close();
										}
									}
								}
								request.setAttribute("isRunNowPressed", "true");
							}
							break;
						}
					}
					List<MyReport> rpts = rDao.getAllMyReportsByUser(sessionData.getReportUtil().getUserName());
					request.setAttribute(MY_REPORTS, rpts);
					request.setAttribute(COMPLETED_REPORTS, isTest? null:JasperUtils.GetFilesInDirectory(new File(sessionData.getReportUtil().getReportsFolder())));
			
					setPrivateSessionData(sessionData.getSessionId(), sessionData);
					if (!isException) {
						if (!isTest) {
							PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/jsp/reportManager.jsp");
							dispatcher.include(request, response);
						}
					}
			} catch (PortletException e) {
				logger.error("Exception: "+e.getMessage());
			} catch (IOException e) {
				logger.error("Exception: "+e.getMessage());
			} catch (JRException e) {
				logger.error("Exception: "+e.getMessage());
			} catch (NamingException e) {
				logger.error("Exception: "+e.getMessage());
			} catch (SQLException e) {
				logger.error("Exception: "+e.getMessage());
			}
		logger.debug("******Display Manager Data END section***************************"); 
	}
	
	/* (private)this method calls when we show Reporting Application: definition page 
	 * @param RenderRequest request
	 * @param RenderResponse response
	 * @return void
	 */	
	private void displayDefinitionData(RenderRequest request, RenderResponse response) {
		logger.debug("******Display Definition Data START section***************************"); 
		ReportingPortletDataPerUser sessionData = getPrivateSessionData(request);
		boolean isException = false;
		if (sessionData != null)
		{
			try {
				List<Report> reports = null;
				Report currentReport = null;
				List<ReportView> reportViews = null;
				ReportView currentReportView = null;
				List<OutputFormat> outputFormats = null;
				sessionData.setPrint(null);
				String prm = "";
			
				//verify session
				setSessionId(request);
			
				// Read all available reports
				reports = rDao.getAllReports();
				request.setAttribute(ALL_REPORTS, reports);
				logger.debug("Report's count:" + reports.size());

				if (reports.size() != 0) {
					// set selectedReports
					sessionData.setCurrentReportId((sessionData.getCurrentReportId() == null) ? reports.get(0).getId() : sessionData.getCurrentReportId());
					request.setAttribute(CURRENT_REPORT_ID, sessionData.getCurrentReportId());

					currentReport = rDao.getById(sessionData.getCurrentReportId());
					sessionData.setReportName(currentReport.getName());
				
					reportViews = rDao.getAllViewsByReport(currentReport.getId());
					request.setAttribute(ALL_REPORT_VIEW, reportViews);
					logger.debug("Report Views count:" + reportViews.size()); 

					Response saveSuccess = null;
				
					if (reportViews.size() != 0) {
						// Set selected view id
						if (sessionData.getCurrentViewId() != null) {
							currentReportView = rDao.getReportViewById(sessionData.getCurrentViewId());
						}
						if (!SimpleUtils.isViewinCollection(reportViews,currentReportView)) {
							logger.warn("current view id:" + sessionData.getCurrentViewId() + " does not exists in selected report"); 
							currentReportView = reportViews.get(0);
							sessionData.setCurrentViewId(currentReportView.getId());
						}

						request.setAttribute(CURRENT_REPORT_VIEW, currentReportView);

						// set report format
						outputFormats = rDao.getReportViewFormatsByViewId(sessionData.getCurrentViewId());
						request.setAttribute(ALL_OUTPUTFORMATS, outputFormats);
						logger.debug("selected format:"+sessionData.getReportUtil().getReportFormat().toString()); 
						if (sessionData.getReportUtil().getReportFormat() == null || !SimpleUtils.isFormatinCollection(outputFormats, sessionData.getReportUtil().getReportFormat().toString()))
						{
							sessionData.getReportUtil().setReportFormat(ReportingEnums.Format.valueOf(outputFormats.get(0).getName()));
							logger.debug("current view id:" + sessionData.getCurrentViewId()	+ " does not exists in selected output. get the another one");
						}
						
						request.setAttribute(SELECTED_FORMAT, sessionData.getReportUtil().getReportFormat().toString());
					
						sessionData.setDesign(JasperUtils.loadReport(currentReportView.getJrxml().getBytes("UTF-8")));
						logger.debug("design was changed for reportView:"+currentReportView.getId()); 

						if (sessionData.getReportUtil().getParameters() == null)
						{
							sessionData.getReportUtil().setParameters(new HashMap<String, String>());
						}
					
						rDao.getAllMyReportsByUser(sessionData.getReportUtil().getUserName());
						request.setAttribute(MY_REPORTS, rDao.getAllMyReportsByUser(sessionData.getReportUtil().getUserName()));
						
						sessionData = JasperUtils.setupParameters(sessionData);
//?						setPrivateSessionData(sessionData.getSessionId(), sessionData);
						
						if (sessionData.getModel()!=null && sessionData.getBtnPressedId()!=null)
						{
							logger.debug("All parameters are successfully filled");
//?							sessionData = getPrivateSessionData(request);
							switch(sessionData.getBtnPressedId())
							{
							case viewBtn:
								Connection con = null;
								if (currentReportView.getDatasourceId() != 0l)
								{
									con = JasperUtils.getReportViewConnection(rDao.getReportDSById(currentReportView.getDatasourceId()));
									logger.debug("Report View:"+currentReportView.getId()+" uses the connection with id:"+currentReportView.getDatasourceId());
								}
								else
								{
									if (!isTest) con = JasperUtils.getDataSource().getConnection();
									logger.debug("Report View:"+currentReportView.getId()+" uses default connection"); 
								}
								HashMap<String, Object> mdl = sessionData.getModel();
								mdl.put(JRParameter.REPORT_FILE_RESOLVER, new CustomFileResolver(rDao.setLogMaster(currentReportView.getId(), sessionData.getReportUtil().getUserName(), sessionData.getParameters())));
								try {
									JasperReport jasperReport = JasperCompileManager.compileReport(sessionData.getDesign());
									if (jasperReport.getWhenNoDataTypeValue() == WhenNoDataTypeEnum.NO_PAGES) {
										jasperReport.setWhenNoDataType(WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);
									}
									sessionData.setPrint(JasperFillManager.fillReport(jasperReport, mdl, con));
									sessionData.setModel(mdl);
								}
								catch (Exception ex) {
									String urlBack = PortletURLUtil.getCurrent(request, response).toString();
									urlBack = urlBack.substring(0,urlBack.indexOf("?"));
									request.setAttribute(LINK_TO_BACK, urlBack);
									request.setAttribute(LINK_TO_MESSAGE, "There is an Error in the Report Query, please contact the System Administrator");
									PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/jsp/index.jsp");
									dispatcher.include(request, response);	
									isException = true;
									sessionData.setBtnPressedId(ReportingEnums.ButtonIds.cancelBtn);
								}
								finally {
									if (con != null) {
										con.close();
									}
								}
								break;
							case saveBtn:
								/*ByteArrayOutputStream baos = new ByteArrayOutputStream();
								ObjectOutputStream oout = new ObjectOutputStream(baos);
								oout.writeObject(populateData(sessionData));
								oout.close();*/
//								sessionData = getPrivateSessionData(request);
								sessionData.getReportUtil().setViewId(currentReportView.getId());
								if (!SimpleUtils.isStringEmpty(sessionData.getMyReportName())) {
									saveSuccess = rDao.saveMyReport(sessionData.getMyReportName(), sessionData.getReportUtil().getUserName(), currentReportView.getId(), JasperUtils.putReportUtilToArray(populateData(sessionData))/*baos.toByteArray()*/, sessionData.getReportUtil().getMyReportId());
									logger.debug("Save is success:" + saveSuccess.isIsSuccess());
								}
								else {
									saveSuccess = new Response();
									saveSuccess.setIsSuccess(false);
									logger.warn("Save is not success because myreport's name is empty or null");
								}
								
								if (saveSuccess.isIsSuccess())
								{
									sessionData.getReportUtil().setMyReportId(rDao.getMyReportByNameAndLoggedUserId(sessionData.getMyReportName(), sessionData.getReportUtil().getUserName()).getId());
									setPrivateSessionData(sessionData.getSessionId(), sessionData);
									scheduleReport(request);
									displayManagerData(request, response); //display reportManager page
								}
								else
								{
									setPrivateSessionData(sessionData.getSessionId(), sessionData);
									scheduleReport(request);
								}

								break;
							}
						}
						HashMap<String, String> prmValues = sessionData.getReportUtil().getParameters();
						ArrayList<Object> prms = new ArrayList<Object>();
						for (JRParameter p : sessionData.getDesign().getParameters()) {
							if (!p.isSystemDefined() && p.isForPrompting()) {
								prms.add(p);
								if (prmValues.get(p.getName()) == null) {
									prmValues.put(p.getName(), "");
								}
							
								if (p.getValueClassName().equals("java.lang.Boolean") && SimpleUtils.isStringEmpty(prmValues.get(p.getName()))) 
								{
									prm +=String.format(" %s: %s",p.getName(),"false");
								}
								else if(p.getValueClassName().equals("java.lang.Boolean") )
								{
									prm +=String.format(" %s: %s",p.getName(),"true");
								}
								else if(!SimpleUtils.isStringEmpty(prmValues.get(p.getName())))
								{
									prm +=String.format(" %s: %s",p.getName(),prmValues.get(p.getName()));
								}
								p.setDescription(p.getDescription()+"&v&"+prmValues.get(p.getName()));
								logger.debug("Parameter:"+p.getName()+" was added  with the value:" + p.getDescription()); 
							}
						}
						request.setAttribute(REPORT_PARAMETERS, prms);
						sessionData.getReportUtil().setParameters(prmValues);
						logger.debug("All Parameters were set"); 
					}

					request.setAttribute(DISPLAY_SELECTED_REPORT, currentReport.getName());
					request.setAttribute(DISPLAY_SELECTED_TYPE, currentReportView == null ? "" :currentReportView.getName());
					request.setAttribute(DISPLAY_SELECTED_SUMMARY, currentReportView==null || SimpleUtils.isStringEmpty(currentReportView.getContentName())? "" : currentReportView.getContentName());
					request.setAttribute(DISPLAY_SELECTED_PARAMETERS, prm);
					request.setAttribute(IS_SCHEDULER_VISIBLE, sessionData.getReportUtil().getSchedulerVisible());
					request.setAttribute(SCHEDULER_START_DATE, sessionData.getReportUtil().getSchedulerStartDate());
					request.setAttribute(SCHEDULER_FREQUENCY, sessionData.getReportUtil().getSchedulerFrequency());
					request.setAttribute(SCHEDULER_EMAIL, sessionData.getReportUtil().getEmail());
					request.setAttribute(SCHEDULER_RECURRING_COUNT, sessionData.getReportUtil().getSchedulerCountToRun());
					request.setAttribute(SCHEDULER_DAY, sessionData.getReportUtil().getSchedulerDay());
					request.setAttribute(SCHEDULER_IS_CALENDAR, sessionData.getReportUtil().getIsCalendarchoosed());
					request.setAttribute(SCHEDULER_DAY_NAME, sessionData.getReportUtil().getSchedulerRecurringDate());
					request.setAttribute(SCHEDULER_DAY_PREFIX, sessionData.getReportUtil().getSchedulerRecurringDatePrefix());
					request.setAttribute(DISPLAY_SELECTED_OUTPUT, sessionData.getReportUtil().getReportFormat() == null ? "" : sessionData.getReportUtil().getReportFormat().toString());

					logger.debug("SCHEDULER_IS_CALENDAR:"+ sessionData.getReportUtil().getIsCalendarchoosed()); 
					logger.debug("SCHEDULER_DAY_NAME:"+ sessionData.getReportUtil().getSchedulerRecurringDate()); 
					logger.debug("SCHEDULER_DAY_PREFIX:"+ sessionData.getReportUtil().getSchedulerRecurringDatePrefix()); 

					logger.debug("data information are set"); 
					
					request.setAttribute(TAB_SELECTED, sessionData.getTabSelected());
					logger.debug("Tab Selected:" + sessionData.getTabSelected());

					if ((sessionData.getBtnPressedId()== null || sessionData.getBtnPressedId()!=ReportingEnums.ButtonIds.viewBtn)&& sessionData.getPrint() != null)
					{
						sessionData.getReportUtil().setParameters(null);
						logger.debug("ParamValues was cleared"); 
					}
					request.setAttribute("isViewPressed", sessionData.getBtnPressedId()!=null && sessionData.getPrint() != null);
				
					request.setAttribute("HELP_URL",System.getProperty("help.url", ""));
					logger.debug("HELP URL is:"+System.getProperty("help.url", "")); 
					
					request.setAttribute(MY_REPORT_NAME,sessionData.getMyReportName());
				
					request.setAttribute(MY_REPORT_NAME_IN_THE_DB, sessionData.getMyReportNameInDB());
				
					logger.debug("Reports Home path:"+sessionData.getReportUtil().getReportsFolder());
					
					String email = isTest ? mockData.getEmail() :((ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY)).getUser().getDisplayEmailAddress();
					
					request.setAttribute(LOGGED_USER_EMAIL, email);
					logger.debug("Logged User Email: "+ email.replace('@', '_'));
					
					logger.debug("******Display Definition Data END section***************************"); 
					if (!isException) {
						if (!(saveSuccess != null && saveSuccess.isIsSuccess()))
						{
							sessionData.setBtnPressedId(null);
							setPrivateSessionData(sessionData.getSessionId(), sessionData);
							if (!isTest) {
								PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/jsp/view.jsp");
								dispatcher.include(request, response);
							}
						}
						else
						{
							sessionData.clearData();
						}
					}
				}
				else
				{
					String urlBack = PortletURLUtil.getCurrent(request, response).toString();
					urlBack = urlBack.substring(0,urlBack.indexOf("?"));
					request.setAttribute(LINK_TO_BACK, urlBack);
					request.setAttribute(LINK_TO_MESSAGE, "There is an Error: NO REPORTS, please contact the System Administrator");
					if (!isTest) {
						PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/jsp/index.jsp");
						dispatcher.include(request, response);
					}
					isException = true;
					sessionData.setBtnPressedId(null);
					sessionData.setWindow(ReportingEnums.Window.reportManager);
				}
			} catch (SQLException e) {
				logger.error("Exception: "+e.getMessage());
			} catch (NamingException e) {
				logger.error("Exception: "+e.getMessage());
			} catch (PortletException e) {
				logger.error("Exception: "+e.getMessage());
			} catch (JRException e) {
				logger.error("Exception: "+e.getMessage());
			} catch (IOException e) {
				logger.error("Exception: "+e.getMessage());
			}
			setPrivateSessionData(sessionData.getSessionId(), sessionData);
		}
		else
		{
			logger.warn("Your session is expired");
		}
	}

	/* (private)this method calls when we save myReport. It prepares data to save 
	 * @param ReportingPortletDataPerUser sessionData
	 * @return ReportUtil
	 */	
	private ReportUtil populateData(ReportingPortletDataPerUser sessionData)
	{
		//ReportUtil data = new ReportUtil();
/*		data.setReportFormat(sessionData.getFormat());
		data.setViewId(sessionData.getCurrentViewId());
		data.setUserName(sessionData.getLoggedUser());
		data.setParameters(sessionData.getParamValues());
		data.setSchedulerStartDate(sessionData.getSchedulerStartDate());
		data.setEmail(sessionData.getEmail());
		data.setMyReportId(sessionData.getSelectedMyReport());
		data.setSchedulerVisible(sessionData.getSchedulerVisible());*/

		if (sessionData.getReportUtil().getSchedulerStartDate() != null && sessionData.getReportUtil().getSchedulerVisible()) 
		{
			//setup CronTrigger
			CronTriggerExpr trigExpr = new CronTriggerExpr();
			
			Calendar d = Calendar.getInstance();
			d.setTime(sessionData.getReportUtil().getSchedulerStartDate());
			trigExpr.setSeconds(""+d.get(Calendar.SECOND));
			trigExpr.setMinutes(""+d.get(Calendar.MINUTE));
			trigExpr.setHours(""+d.get(Calendar.HOUR_OF_DAY));

			switch (sessionData.getReportUtil().getSchedulerFrequency()) {
			case OneTime:
				trigExpr.setDayOfMonths(""+d.get(Calendar.DAY_OF_MONTH));
				trigExpr.setDayOfWeek("?");
				trigExpr.setMonths(""+(d.get(Calendar.MONTH)+1));
				trigExpr.setYear(""+d.get(Calendar.YEAR));
				break;
			case Daily:
				trigExpr.setDayOfMonths("*");
				trigExpr.setMonths("*");
				trigExpr.setDayOfWeek("?");
				trigExpr.setYear("*");
				break;
			case Weekly:
				trigExpr.setDayOfMonths("?");
				trigExpr.setMonths("*");
				trigExpr.setDayOfWeek(""+sessionData.getReportUtil().getSchedulerDay());
				trigExpr.setYear("*");
				break;
			case Monthly:
				if (sessionData.getReportUtil().getIsCalendarchoosed()) {
					trigExpr.setDayOfMonths(""+sessionData.getReportUtil().getSchedulerDay());
					trigExpr.setMonths("*");
					trigExpr.setDayOfWeek("?");
					trigExpr.setYear("*");					
				}
				else
				{
					if (!sessionData.getReportUtil().getSchedulerRecurringDate().trim().equals("0"))
					{
						trigExpr.setDayOfWeek(""+sessionData.getReportUtil().getSchedulerRecurringDate()/*.replaceAll(",", sessionData.getSchedulerRecurringDatePrefix()+",")*/+sessionData.getReportUtil().getSchedulerRecurringDatePrefix());
						trigExpr.setDayOfMonths("?");
					}
					else
					{
						trigExpr.setDayOfWeek("?");	
						trigExpr.setDayOfMonths(""+
							sessionData.getReportUtil().getSchedulerRecurringDatePrefix() != null && sessionData.getReportUtil().getSchedulerRecurringDatePrefix().equals("L") 
							? "L":sessionData.getReportUtil().getSchedulerRecurringDatePrefix().substring(1));
					}
					trigExpr.setMonths("*");
					trigExpr.setYear("*");
				}
				break;
			case Yearly:
				/*if (sessionData.getIsCalendarchoosed()) {
					trigExpr.setMonths(""+sessionData.getSchedulerDay());
					trigExpr.setDayOfWeek("?");
					trigExpr.setYear("*");		
					trigExpr.setDayOfMonths(""+d.get(Calendar.DAY_OF_MONTH));
				}
				else
				{*/
				if (!sessionData.getReportUtil().getSchedulerRecurringDate().trim().equals("0")){
					trigExpr.setDayOfMonths("?");
					trigExpr.setDayOfWeek(""+sessionData.getReportUtil().getSchedulerRecurringDate()/*.replaceAll(",", sessionData.getSchedulerRecurringDatePrefix()+",")*/+sessionData.getReportUtil().getSchedulerRecurringDatePrefix());
				}
				else
				{
					trigExpr.setDayOfMonths(""+
							sessionData.getReportUtil().getSchedulerRecurringDatePrefix() != null && sessionData.getReportUtil().getSchedulerRecurringDatePrefix().equals("L") 
							? "L":sessionData.getReportUtil().getSchedulerRecurringDatePrefix().substring(1));
					trigExpr.setDayOfWeek("?");
					
				}
				trigExpr.setMonths(""+sessionData.getReportUtil().getSchedulerDay());
				trigExpr.setYear("*");
				/*}*/
				break;
			}
			
			if (sessionData.getReportUtil().getSchedulerCountToRun()>0) {
				sessionData.getReportUtil().setTriggerExpr(trigExpr);
			}
			else
			{
				sessionData.getReportUtil().setTriggerExpr(null);
			}
			logger.debug("Trigger time is:"+sessionData.getReportUtil().getTriggerExpr().getExpression());
			
		} else if(sessionData.getReportUtil().getTriggerId() != null)
		{
			SchedulerManager.deleteJobAndTrigger(sessionData.getReportUtil().getTriggerId());
		}
		logger.debug("*******************************************************************************");
		logger.debug("I'm in populateData trigger id is " + sessionData.getReportUtil().getTriggerId());
		logger.debug("*******************************************************************************");

		if (sessionData.getReportUtil().getTriggerId() == null){
		sessionData.getReportUtil().setTriggerId(new java.util.UUID(
			new java.util.Date().getTime(),  new java.util.Date().getTime()) .toString() );
		}

		logger.debug("*******************************************************************************");
		logger.debug("I'm in populateData trigger change to " + sessionData.getReportUtil().getTriggerId());
		logger.debug("*******************************************************************************");
		
		setPrivateSessionData(sessionData.getSessionId(), sessionData);
		
		return sessionData.getReportUtil();
	}

	/* (private)this method calls when log in as user to save his unique data (report id, parameters values, etc) 
	 * @param PortletRequest request
	 * @return ReportingPortletDataPerUser
	 */	
	private ReportingPortletDataPerUser setSessionId(PortletRequest request)
	{
		if (!usersPrivateData.containsKey(request.getRequestedSessionId()))
		{
			ReportingPortletDataPerUser ru = new ReportingPortletDataPerUser();
			/*create a folder for generated reports if it needs */
			File JBossHome = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()).getParentFile().getParentFile().getParentFile().getParentFile().getParentFile().getParentFile();
			String email = isTest ? mockData.getEmail() :((ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY)).getUser().getDisplayEmailAddress();
			String loggedUser;
			File repHome;
			if (request.getRemoteUser() != null) {
				loggedUser = isTest ? request.getRemoteUser() :request.getRemoteUser() + "_"+ PortalUtil.getUserName(Long.parseLong(request.getRemoteUser()), "Anonymous");
				repHome = new File(isTest? email.replace('@', '_'):JBossHome.getPath()+File.separator+ "Reports" + File.separator + request.getRemoteUser()+"_"+email.replace('@', '_'));
			}
			else
			{
				loggedUser = "Anonymous";
				repHome =  new File(isTest? email.replace('@', '_'):JBossHome.getPath()+File.separator+ "Reports" + File.separator + email.replace('@', '_'));
			}
			logger.debug("Logged User: "+ loggedUser + " email:" +email);

			logger.debug("repHome="+repHome.getPath());
			ru.getReportUtil().setReportsFolder(repHome.getPath());
			if (!isTest) repHome.mkdirs();
		
			ru.setSessionId(request.getRequestedSessionId());
			ru.getReportUtil().setUserName(loggedUser);
			usersPrivateData.put(request.getRequestedSessionId(), ru);
		}
		return getPrivateSessionData(request);
	}
	
	/* (private)this method calls when need read some information for user from memory 
	 * @param PortletRequest request
	 * @return ReportingPortletDataPerUser
	 */	
	public ReportingPortletDataPerUser getPrivateSessionData(PortletRequest request)	{
		ReportingPortletDataPerUser res = null;
		if (usersPrivateData.containsKey(request.getRequestedSessionId()))
		{
			res = usersPrivateData.get(request.getRequestedSessionId());
			setPrivateSessionData(res.getSessionId(), res);
		}
		else
		{
			res = setSessionId(request);
		}
		logger.debug("Session id is "+res.getSessionId()); 
		return res;
	}

	/* (private)this method calls when need save some information for user to memory 
	 * @param PortletRequest request
	 * @return ReportingPortletDataPerUser
	 */	
	private void setPrivateSessionData(String sessionId, ReportingPortletDataPerUser data) {
		if (usersPrivateData.containsKey(sessionId)) {
			usersPrivateData.remove(sessionId);
		}
		data.setLastCallSession(new java.util.Date());
		usersPrivateData.put(sessionId, data);
		
		clearExpiredPrivateSessionData();
	}

	/* (private)this method remove session from memory (when user has not done any activity for a hour)  
	 * @return void
	 */	
	private void clearExpiredPrivateSessionData(){
		long t = new Date().getTime();

		ArrayList<String> oldSession = new ArrayList<String>();
		
		//remove old session (inactive more that 1 hour)
		for (String key : usersPrivateData.keySet()){
			 if (t - usersPrivateData.get(key).getLastCallSession().getTime() > (1000*60*60) )
			 {
				 oldSession.add(key);
				 logger.debug("*******INACTIVE SESSION");
				 logger.debug("userName:" + usersPrivateData.get(key).getReportUtil().getUserName());
				 logger.debug("last action:" + usersPrivateData.get(key).getLastCallSession());
				 logger.debug("*******");
			 }
		}
		
		for (String key : oldSession) {
			usersPrivateData.remove(key);
		}
	}

	/* (private)this method calls when we create trigger for scheduler 
	 * @param PortletRequest request
	 * @return void
	 */	
	private void scheduleReport(PortletRequest request)
	{
	  ReportingPortletDataPerUser sessionData = getPrivateSessionData(request);  
	
	  ReportUtil reportUtil = populateData(sessionData);
	  
	  if(reportUtil.getTriggerExpr() != null) {
		   logger.debug("expr is"+ reportUtil.getTriggerExpr().getExpression());
	  }
	  
	  SchedulerManager.addJobAndTrigger(reportUtil);
	  
	  logger.debug("Report was successfully scheduled");
	}
	
	public void setIsTest (boolean isTest) {
		this.isTest = isTest;
	}
}
